package com.uestc.ui;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.uestc.config.DownloadPath;
import com.uestc.config.InitPath;
import com.uestc.config.RouterConfig;
import com.uestc.context.BaseContext;
import com.uestc.entity.FileData;
import com.uestc.entity.Result;
import com.uestc.utils.HuffmanCoding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;
import javafx.util.Callback;

import java.io.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.net.URI;


public class NetDiskView {

    public static void showNetDiskDialog() {
        Stage dialog = new Stage();
        dialog.setTitle("网盘");

        TableView<FileData> tableView = initializeTableView(getFileData());

        // 创建上传、刷新和返回按钮
        Button uploadButton = new Button("上传文件");
        Button refreshButton = new Button("刷新"); // 新增刷新按钮
        Button backButton = new Button("返回");

        // 设置按钮事件
        uploadButton.setOnAction(event -> {
            handleUploadFile();
            dialog.close();
            showNetDiskDialog();
        });
        refreshButton.setOnAction(event -> {
            dialog.close();
            showNetDiskDialog();
        }); // 新增刷新按钮事件
        backButton.setOnAction(event -> dialog.close());

        // 创建HBox布局并添加按钮
        HBox buttonBox = new HBox(10); // 10是按钮之间的间距
        buttonBox.getChildren().addAll(uploadButton, backButton); // 先添加uploadButton和backButton
        HBox.setHgrow(backButton, Priority.NEVER); // 确保backButton不会拉伸

        // 添加刷新按钮并设置其靠右对齐
        buttonBox.getChildren().add(refreshButton);
        HBox.setHgrow(refreshButton, Priority.ALWAYS); // 让refreshButton拉伸并靠右

        // 创建VBox布局并添加表格视图和按钮行
        VBox root = new VBox(10); // 10是组件之间的间距
        root.getChildren().addAll(tableView, buttonBox);

        dialog.setScene(new Scene(root, 800, 600));
        dialog.show();
    }


    private static List<FileData> getFileData() {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(RouterConfig.router + "files/list"))
                .header("Accept", "application/json")
                .header("authentication", BaseContext.getToken())
                .GET()
                .build();

        HttpResponse<String> response = null;
        try {
            response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        Result result = JSON.parseObject(response.body().toString(), Result.class);
        String json = result.getData().toString();
        List<FileData> dataList = JSON.parseObject(json, new TypeReference<List<FileData>>() {
        });
        return dataList;
    }

    private static TableView<FileData> initializeTableView(List<FileData> dataList) {
        TableView<FileData> tableView = new TableView<>();
        ObservableList<FileData> data = FXCollections.observableArrayList();
        data.addAll(dataList);

        TableColumn<FileData, String> fileNameColumn = new TableColumn<>("File Name");
        fileNameColumn.setCellValueFactory(new PropertyValueFactory<>("fileName"));

        TableColumn<FileData, String> fileTypeColumn = new TableColumn<>("File Type");
        fileTypeColumn.setCellValueFactory(new PropertyValueFactory<>("fileType"));

        TableColumn<FileData, Long> fileSizeColumn = new TableColumn<>("File Size");
        fileSizeColumn.setCellValueFactory(new PropertyValueFactory<>("fileSize"));

        TableColumn<FileData, LocalDateTime> createTimeColumn = new TableColumn<>("Create Time");
        createTimeColumn.setCellValueFactory(new PropertyValueFactory<>("createTime"));

        // 添加一个新列用于下载按钮
        TableColumn<FileData, Button> downloadColumn = new TableColumn<>("下载");

        downloadColumn.setCellFactory(new Callback<TableColumn<FileData, Button>, TableCell<FileData, Button>>() {
            @Override
            public TableCell<FileData, Button> call(TableColumn<FileData, Button> param) {
                return new TableCell<FileData, Button>() {
                    private Button btn;

                    @Override
                    public void updateItem(Button item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setGraphic(null);
                            btn = null;
                        } else {
                            btn = new Button("下载");
                            if (getIndex() >= 0) {
                                FileData fileData = getTableView().getItems().get(getIndex());
                                btn.setOnAction(event -> downloadFile(fileData.getId(), fileData.getFileName()));
                            }
                            setGraphic(btn);
                        }
                    }
                };
            }
        });

        tableView.getColumns().addAll(fileNameColumn, fileTypeColumn, fileSizeColumn, createTimeColumn, downloadColumn);
        tableView.setItems(data);

        return tableView;
    }

    private static void downloadFile(Integer id, String fileName) {
        // 创建HttpClient实例
        HttpClient client = HttpClient.newHttpClient();

        // 构建请求URI，替换routerConfig.router为你的服务器地址
        String requestUri = RouterConfig.router + "files/restore/" + id;

        // 创建HttpRequest
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(requestUri))
                .header("Accept", "application/json")
                .header("authentication", BaseContext.getToken())
                .GET()
                .build();

        try {
            // 发送请求并获取响应
            HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
            // 检查响应状态码
            if (response.statusCode() == 200) {
                byte[] fileContent = response.body();
                // 响应成功，处理文件下载
                HuffmanCoding.decompress(fileContent, DownloadPath.path);
            } else {
                // 响应失败，打印错误信息
                System.out.println("文件下载失败，状态码：" + response.statusCode());
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }


    private static void handleUploadFile() {
        Stage stage = new Stage();
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择要上传的文件");

        // 显示打开文件对话框
        File file = fileChooser.showOpenDialog(stage);

        if (file != null) {
            HttpClient client = HttpClient.newHttpClient();
            String boundary = "---------------------------boundary";
            String CRLF = "\r\n";

            // 构建多部分请求体的开始部分
            String multipartHeader = "--" + boundary + CRLF +
                    "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + CRLF +
                    "Content-Type: application/octet-stream" + CRLF + CRLF;

            // 创建一个ByteArrayOutputStream来收集请求体的各个部分
            ByteArrayOutputStream bodyStream = new ByteArrayOutputStream();
            try {
                // 写入multipartHeader
                bodyStream.write(multipartHeader.getBytes(StandardCharsets.UTF_8));

                // 使用FileInputStream读取文件内容并写入到bodyStream
                try (FileInputStream fileInputStream = new FileInputStream(file)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                        bodyStream.write(buffer, 0, bytesRead);
                    }
                }

                // 写入请求体的结束部分
                bodyStream.write(CRLF.getBytes(StandardCharsets.UTF_8));
                bodyStream.write(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8));

                // 创建BodyPublisher
                HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.ofInputStream(
                        () -> new ByteArrayInputStream(bodyStream.toByteArray()));

                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(RouterConfig.router + "files/upload"))
                        .header("Content-Type", "multipart/form-data; boundary=" + boundary)
                        .header("authentication", BaseContext.getToken())
                        .POST(bodyPublisher)
                        .build();

                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

                if (response.statusCode() == 200) {
                    System.out.println("文件上传成功");
                } else {
                    System.out.println("文件上传失败，状态码：" + response.statusCode());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
